package gui.klan;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import base.UserObject;
import base.check.Check;
import base.patterns.delegate.Delegate;
import base.patterns.delegate.Delegate.Slot;
import base.patterns.operation.Function;
import base.value.Value;

public class UserFrame<Model> extends UserObject{
	public final Delegate<Void, JFrame> initFrame = new Delegate<Void, JFrame>();
	
	public final Delegate<Void, Model> setModel = new Delegate<Void, Model>();
	public final Delegate<Model, Void> getModel = new Delegate<Model, Void>();
	
	private JFrame jFrame; 

	public UserFrame() {
		jFrame = new JFrame("");
	}
	
	public void init(){
		if ( Delegate.isConnected(initFrame)) initFrame.call(jFrame);
	}
	
	public void show(){
		jFrame.setVisible(true);
	}

	public static class FrameStringController {
		private Value.String value = new Value.String("hello");
		
		private JTextArea jTextArea; 
		private JButton jButton1 = new JButton("Click");
		public final Function<Void, JFrame> initJFrame = new Function<Void, JFrame>() {
			 
			@Override
			public Void call(JFrame frame) {
				FlowLayout flowLayout = new FlowLayout();
				flowLayout.setAlignment(FlowLayout.LEFT);
				frame.setLayout(flowLayout);
				
				jButton1 = new JButton("Click");
				jTextArea = new JTextArea( value.get() );
				frame.getContentPane().add( new JScrollPane(jTextArea));
				frame.getContentPane().add(jButton1);
				
				jButton1.addActionListener(new ActionListener() {
	                 public void actionPerformed(ActionEvent e)
	                 {
	                	 FrameStringController.this.value.set( jTextArea.getText() );
	                 }
				});
				
				frame.setSize(400, 200);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				return null;
			}
			
		};
		 
		public final  Function<Void, String> setModel = new Function<Void, String>(){

			@Override
			public Void call(String model) {
				value.set(model);
				return null;
			}
			
		};
		
		public final Function<String, Void> getModel = new Function<String, Void>(){

			@Override
			public String call(Void missing) {
				return value.get();
			}
		};
		
		public void connect(UserFrame<String> frame){
			Check.notNull(frame, "frame");
			
			Delegate.connect(frame.initFrame, new Slot<Void, JFrame>(this.initJFrame));
			Delegate.connect(frame.getModel,  new Slot<String, Void>(this.getModel));
			Delegate.connect(frame.setModel,  new Slot<Void, String>(this.setModel));
			
			frame.init();
		}
		
	}
	
	 public static void main(String[] args){
		 UserFrame<String> frame = new UserFrame<String>();
		 
		 FrameStringController controller = new FrameStringController();
		 controller.connect(frame);
		 
		 frame.show();
	 }

	public static void setFrameSizeFormScreenSize(JFrame mainFrame) {
		int inset = 50;
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		mainFrame.setBounds(inset, inset, screenSize.width / 2, screenSize.height/2);
	}
}
